﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

/* Author: Leslie Xin
 * E-Mail: lesliexin@outlook.com
 * WebSite: http://www.lesliexin.com
 * Datetime: 2025-04-19 06:55:03
 * 
 * V1
 */

namespace LeslieXin.SimpleLiveDataFeed
{
    /// <summary>
    /// 使用起来超简单的实时采集数据显示，基于MSChart
    /// </summary>
    public class SimpleLiveDataFeed
    {
        /// <summary>
        /// 使用起来超简单的实时采集数据显示，基于MSChart
        /// </summary>
        /// <param name="chart">MSChart，为NULL时，自动生成</param>
        /// <param name="titleY">Y轴标题</param>
        /// <param name="dataSourceTitleColors">数据源名称与颜色</param>
        /// <param name="averageColor">平均值的颜色</param>
        /// <param name="interval">采集间隔，默认：500ms</param>
        /// <param name="showAverage">是否显示平均值，默认：显示</param>
        /// <param name="titleX">X轴标题，默认：当前时间</param>
        /// <param name="showDataDuration">显示最近多少秒的数据，默认：30s</param>
        public SimpleLiveDataFeed(Chart chart,  string titleY, List<Tuple<string, Color>> dataSourceTitleColors,  Color averageColor, int interval = 500, bool showAverage = true, string titleX = "当前时间",int showDataDuration=30)
        {
            if (chart == null)
            {
                MSChart = new Chart();
            }
            else
            {
                MSChart = chart;
            }
            _showAverage = showAverage;
            _showDataDuration = showDataDuration;
            InitChart(titleY, dataSourceTitleColors,averageColor,showAverage,titleX);
            dataTimer = new Timer();
            dataTimer.Interval = interval; 
            dataTimer.Tick += DataTimer_Tick;
        }

        /// <summary>
        /// 定时获取采集到的数据，返回数据源名称及采集到的值
        /// </summary>
        public event Func<List<Tuple<string, double>>> DataAcquisition;

        private Timer dataTimer;
        private const int MaxPoints = 100; // 最大显示点数
        /// <summary>
        /// 当实例化时不传入MSChart时，自动生成的MSChart
        /// </summary>
        public Chart MSChart { get; set; }
        private bool _showAverage=true;
        private int _showDataDuration = 30;

        void InitChart(string titleY, List<Tuple<string, Color>> dataSourceTitleColors, Color averageColor, bool showAverage = true, string titleX="当前时间")
        {
            // 设置图表基本属性
            MSChart.Dock = DockStyle.Fill;

            // 清除可能存在的旧数据
            MSChart.Series.Clear();
            MSChart.ChartAreas.Clear();

            // 创建图表区
            ChartArea chartArea = MSChart.ChartAreas.Add("MainArea");
            chartArea.AxisX.Title = titleX;
            chartArea.AxisY.Title = titleY;
            chartArea.AxisX.LabelStyle.Format = "HH:mm:ss";
            chartArea.AxisX.IntervalType = DateTimeIntervalType.Seconds;
            chartArea.AxisX.Interval = 5; // 每5秒显示一个标签

            // 启用滚动和缩放
            chartArea.CursorX.IsUserEnabled = true;
            chartArea.CursorX.IsUserSelectionEnabled = true;
            chartArea.AxisX.ScaleView.Zoomable = true;
            chartArea.AxisX.ScrollBar.Enabled = false;

            if (dataSourceTitleColors == null)
            {
                dataSourceTitleColors = new List<Tuple<string, Color>>();
            }
            foreach (var item in dataSourceTitleColors)
            {
                Series series1 = MSChart.Series.Add(item.Item1);
                series1.ChartType = SeriesChartType.Spline; // 平滑曲线
                series1.BorderWidth = 2;
                series1.Color = item.Item2;
            }
            if (showAverage)
            {
                Series avgSeries = MSChart.Series.Add("平均值");
                avgSeries.ChartType = SeriesChartType.Spline;
                avgSeries.BorderWidth = 4;
                avgSeries.Color = averageColor;
            }

            // 设置图例
            MSChart.Legends.Add(new Legend());

        }

        /// <summary>
        /// 开始显示采集到的数据
        /// </summary>
        public void Start()
        {
            dataTimer.Start();
        }

        /// <summary>
        /// 停止显示
        /// </summary>
        public void Stop()
        {
            dataTimer.Stop();
        }

        private void DataTimer_Tick(object sender, EventArgs e)
        {
            var data = DataAcquisition?.Invoke();
            if (data == null) return;
            if (data.Count == 0) return;

            double avgValue = data.Average(item => item.Item2);

            DateTime now = DateTime.Now;

            // 添加数据点到各个系列
            foreach (var item in data)
            {
                MSChart.Series[item.Item1].Points.AddXY(now, item.Item2);
            }
            if (_showAverage)
            {
                MSChart.Series["平均值"].Points.AddXY(now, avgValue);
            }

            // 控制数据点数量，保持滚动效果
            foreach (Series series in MSChart.Series)
            {
                if (series.Points.Count > MaxPoints)
                {
                    series.Points.RemoveAt(0);
                }
            }

            // 自动调整X轴范围，实现滚动效果
            ChartArea area = MSChart.ChartAreas[0];
            double maxX = now.ToOADate();
            double minX = now.AddSeconds(-_showDataDuration).ToOADate(); // 显示最近30秒数据
            area.AxisX.ScaleView.Zoom(minX, maxX);
        }

    }
}
